package com.hst.capacity.domain.service.impl;

import cn.hutool.core.util.ObjUtil;
import com.alicp.jetcache.anno.Cached;
import com.hst.capacity.domain.exception.BusinessException;
import com.hst.capacity.domain.model.entity.auth.UserEntity;
import com.hst.capacity.domain.model.response.auth.LoginUser;
import com.hst.capacity.domain.service.UserService;
import com.hst.capacity.infra.persistence.jpa.UserRepository;
import com.hst.capacity.infra.persistence.jpa.auth.UserRoleRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

@Slf4j
@Service
public class UserServiceImpl implements UserService, UserDetailsService {

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private UserRoleRepository userRoleRepository;

    /**
     * 根据userId获取用户实体
     *
     * @param userId 用户ID
     * @return UserEntity
     */
    @Override
    public UserEntity getUser(String userId) {
        return userRepository.findById(userId).get();
    }

    /**
     * 根据用户名、密码进行身份验证。
     *
     * @param username 用户名
     * @param password 密码
     * @return UserEntity
     */
    @Override
    public LoginUser authenticate(String username, String password) {

        UsernamePasswordAuthenticationToken userToken = new UsernamePasswordAuthenticationToken(username, password);
        Authentication authentication = null;
        try {
            authentication = authenticationManager.authenticate(userToken);
        } catch (Exception ex) {
            throw new BusinessException(5002, ex.getMessage());
        }

        if (ObjUtil.isNull(authentication)) {
            throw new BusinessException(5002, "登陆失败！");
        }

        return (LoginUser) authentication.getPrincipal();
    }

    /**
     * 根据userId查询用户角色列表
     *
     * @param userId 用户ID
     * @return List
     */
    @Cached(name = "userAuthorities::", key = "#userId", expire = 600)
    @Override
    public Collection<GrantedAuthority> getAuthorities(String userId) {
        /* 授权 */
        List<String> roles = userRoleRepository.findByUserId(userId);
        Collection<GrantedAuthority> authorities = new ArrayList<>();
        roles.forEach(role -> {
            authorities.add(new SimpleGrantedAuthority("ROLE_" + role.trim()));
        });
        return authorities;
    }

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        // 校验账号是否存在
        UserEntity user = userRepository.findUserEntityByUsername(username);
        if (user == null) {
            throw new BusinessException(5002, "账号不正确！");
        }
        if (user.getUserStatus() == 1) {
            throw new BusinessException(5002, "账号已停用，请联系管理员");
        }

        return new LoginUser(user, getAuthorities(user.getId()));
    }
}
